# -*- coding: utf-8 -*-
'''
设置节点的颜色和形状
'''
import networkx as nx
from neo4j import GraphDatabase
import pandas as pd
import random

url = 'neo4j://159.1.44.26:7687'
username = 'neo4j'
password = 'NJCB#123'

driver = GraphDatabase.driver(url, auth=(username, password))

def import_networkx_graph_to_neo4j(tx, graph):
    G = graph
    print('-' * 20, '操作Neo4j图数据库', '-' * 20)
    try:
        tx.run("MATCH (N) DETACH DELETE N")
    except Exception as e:
        print(e)

    children_id = 1
    for node in graph.nodes():
        node_type = G.nodes[node].get('node_type', None)
        demand_no_lst = G.nodes[node].get('demand_no', None)
        demand_info_lst = G.nodes[node].get('demand_info', None)
        change_content_lst = G.nodes[node].get('change_content', None)
        change_count = G.nodes[node].get('change_count', None)
        main_req_count = G.nodes[node].get('main_req_count', None)
        related_req_count = G.nodes[node].get('related_req_count', None)
        neighbors = set(G.predecessors(node)).union(set(G.successors(node))) - {node}
        system_count = len(neighbors)
        change_count_new = str(change_count) + ' (主: ' + str(main_req_count) + ' 关联: ' + str(related_req_count) + ')'
        info_lst = []
        for i in range(len(demand_info_lst)):
            info_lst.append({"id": demand_no_lst[i], "label": demand_info_lst[i],
                             "children": [{"id": children_id, "label": change_content_lst[i]}]})
            children_id += 1

        system_layer = G.nodes[node].get('system_layer', None)
        system_area = G.nodes[node].get('system_area', None)
        systrm_belong_department = G.nodes[node].get('system_belong_department', None)
        system_manager = G.nodes[node].get('system_no', None)
        system_no = G.nodes[node].get('system_no', None)
        report_date = G.nodes[node].get('report_date', None)

        create_node_query = f"CREATE (:{node_type} {{name: $name, status: $status, ReqCount: $requests_count, " \
                            f"ReqCountStr: $change_count, MainReqCount: $main_req_count, " \
                            f"RelatedReqCount: $related_req_count, " \
                            f"SysCount: $system_count, info: $info, isImportant: $is_important, " \
                            f"systemBelongDepartment: $system_belong_department, " \
                            f"systemManager:$system_manager, systemNo: $system_no," \
                            f"systemLayer: $system_layer, systemArea: $system_area, reportDate: $report_date}})"

        rand_num = random.random()
        if rand_num < 0.5:
            status = 1
        elif rand_num < 0.7:
            status = 2
        # elif rand_num < 0.9:
        #     status = 3
        else:
            status = 4
        tx.run(create_node_query, name=node, status=status, requests_count=change_count,
               change_count=change_count_new, main_req_count=main_req_count, related_req_count=related_req_count,
               system_count=system_count, info=str(info_lst), is_important=0, system_layer=system_layer,
               system_area=system_area, systrm_belong_department=systrm_belong_department,
               system_manager=system_manager, system_no=system_no,
               report_date=report_date)

    for edge in graph.edges(data=True):
        source, target, data = edge
        print(source, target, data)
        source_type, target_type = G.nodes[source].get('node_type', None), G.nodes[target].get('node_type', None)

        create_edge_query = f"MATCH (source:{source_type} {{name: $source_name}}) WITH source" \
                            f"MATCH (target:{target_type} {{name: $target_name}})" \
                            f"CREATE (source) -[:关联{{weight: $weight}}]->(target)"
        tx.run(create_edge_query, source_name=source, target_name=target,
               weight=str(data.get('weight')))


def file_process(df_origin, report_date):

    # ------------------------需求维度信息-------------------------
    demand_info_dict = {}
    for i in range(df_origin.shape[0]):
        system_name = str(df_origin['系统'][i])
        demand_no = str(df_origin['需求编号'][i])
        demand_name = str(df_origin['需求标题'][i])
        change_content = str(df_origin['变更内容'][i])

        if demand_no not in demand_info_dict:
            demand_info_dict[demand_no] = {'demand_name': demand_name, 'change_content': [],
                                           'main_system': '', 'related_systems': []}
        if df_origin['是否主系统'][i] == '是':
            demand_info_dict[demand_no]['main_system'] = system_name

        demand_info_dict[demand_no]['related_systems'].append(system_name)
        demand_info_dict[demand_no]['change_content'].append(change_content)

    # print(demand_info_dict)

    # ------------------------系统维度信息------------------------
    system_info_dict = {}
    for i in range(df_origin.shape[0]):
        system_name = str(df_origin['系统'][i])
        system_belong_department = str(df_origin['所属部门'][i])
        system_manager = str(df_origin['负责人'][i])
        system_no = str(df_origin['系统编号'][i])
        system_layer = str(df_origin['系统所属层'][i])
        system_area = str(df_origin['系统所属域'][i])
        is_main_system_flag = str(df_origin['是否主系统'][i])
        demand_no = str(df_origin['需求编号'][i])
        demand_name = str(df_origin['需求标题'][i])
        change_content = str(df_origin['变更内容'][i])

        if system_name not in system_info_dict:
            system_info_dict[system_name] = {'demand_no': [], 'demand_info': [], 'change_content': [],
                                             'change_count': 0,
                                             'main_req_count': 0, 'related_req_count': 0, 'system_layer': system_layer,
                                             'system_area': system_area,system_belong_department: system_belong_department,
                                             'system_manager': system_manager,'system_no': system_no}

        system_info_dict[system_name]['demand_no'].append(demand_no)
        # system_info_dict[system_name]['demand_info'].append(demand_no + demand_name)
        system_info_dict[system_name]['change_content'].append(change_content)
        system_info_dict[system_name]['change_count'] += 1
        system_info_dict[system_name]['system_layer'] = system_layer
        system_info_dict[system_name]['system_area'] = system_area
        if is_main_system_flag == '是':
            system_info_dict[system_name]['main_req_count'] += 1
            system_info_dict[system_name]['demand_info'].insert(0, '[主]' + demand_no + demand_name)
        else:
            system_info_dict[system_name]['related_req_count'] += 1
            system_info_dict[system_name]['demand_info'].append(demand_no + demand_name)

    print(system_info_dict)

    # -------------------------创建边和节点-------------------------
    G = nx.MultiDiGraph()

    # 创建节点
    nodes_count = 0
    for system_name in system_info_dict:
        print('node:', system_name)
        nodes_count += 1
        G.add_node(system_name, node_type='系统', demand_no=system_info_dict[system_name]['demand_no'],
                   demand_info=system_info_dict[system_name]['demand_info'],
                   change_content=system_info_dict[system_name]['change_content'],
                   change_count=system_info_dict[system_name]['change_count'],
                   main_req_count=system_info_dict[system_name]['main_req_count'],
                   related_req_count=system_info_dict[system_name]['related_req_count'],
                   system_layer=system_info_dict[system_name]['system_layer'],
                   system_area=system_info_dict[system_name]['system_area'],
                   system_belong_department=system_info_dict[system_name]['system_belong_department'],
                   system_manager=system_info_dict[system_name]['system_manager'],
                   system_no=system_info_dict[system_name]['system_no'],
                   report_date=report_date)
    print('nodes_count:', nodes_count)

    # 创建边
    for demand_no in demand_info_dict:
        main_system = demand_info_dict[demand_no]['main_system']
        related_systems_lst = demand_info_dict[demand_no]['related_systems']
        demand_name = demand_info_dict[demand_no]['demand_name']
        if main_system and len(related_systems_lst) > 1:
            print(demand_no, related_systems_lst)
            for related_system in related_systems_lst:
                if related_system != main_system:
                    print('start: %s, end: %s' % (related_system, main_system))
                    G.add_edge(related_system, main_system, weight=str(demand_no))

    # 对孤立点增加自连接的边
    for node in G.nodes():
        neighbors = set(G.predecessors(node)).union(set(G.successors(node)))
        if len(neighbors) == 0:
            # print(node)
            G.add_edge(node, node, weight='')

    # 节点间的多条边聚合
    edge_weights = {}

    for u, v, data in G.edges(data=True):
        print(u, v, data)
        weight = data['weight']
        if (u, v) in edge_weights:
            edge_weights[(u, v)].append(weight)
        else:
            edge_weights[(u, v)] = [weight]

    G.remove_edges_from(list(G.edges))
    for (u, v), weights in edge_weights.items():
        G.add_edge(u, v, weight=','.join(weights))

    for u, v, data in G.edges(data=True):
        print(f"Edge from {u} to {v}, weights: {data['weight']}")

    # 数据写入neo4j图数据库
    with driver.session() as session:
        session.execute_write(import_networkx_graph_to_neo4j, G)
